#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <scsi/sg.h>

typedef struct scsi_ioctl_command {
	unsigned int inlen;
	unsigned int outlen;
	unsigned char data[10];
} Scsi_Ioctl_Command;

#define SCSI_IOCTL_SEND_COMMAND 1
#define SCSI_IOCTL_TEST_UNIT_READY 2
#define SCSI_IOCTL_BENCHMARK_COMMAND 3
#define SCSI_IOCTL_SYNC 4			/* Request synchronous parameters */
#define SCSI_IOCTL_START_UNIT 5
#define SCSI_IOCTL_STOP_UNIT 6

#define TEST_UNIT_READY       0x00
#define REZERO_UNIT           0x01
#define REQUEST_SENSE         0x03
#define FORMAT_UNIT           0x04
#define READ_BLOCK_LIMITS     0x05
#define REASSIGN_BLOCKS       0x07
#define READ_6                0x08
#define WRITE_6               0x0a
#define SEEK_6                0x0b
#define READ_REVERSE          0x0f
#define WRITE_FILEMARKS       0x10
#define SPACE                 0x11
#define INQUIRY               0x12
#define RECOVER_BUFFERED_DATA 0x14
#define MODE_SELECT           0x15
#define RESERVE               0x16
#define RELEASE               0x17
#define COPY                  0x18
#define ERASE                 0x19
#define MODE_SENSE            0x1a
#define START_STOP            0x1b
#define RECEIVE_DIAGNOSTIC    0x1c
#define SEND_DIAGNOSTIC       0x1d
#define ALLOW_MEDIUM_REMOVAL  0x1e

#define SET_WINDOW            0x24
#define READ_CAPACITY         0x25
#define READ_10               0x28
#define WRITE_10              0x2a
#define SEEK_10               0x2b
#define WRITE_VERIFY          0x2e
#define VERIFY                0x2f
#define SEARCH_HIGH           0x30
#define SEARCH_EQUAL          0x31
#define SEARCH_LOW            0x32
#define SET_LIMITS            0x33
#define PRE_FETCH             0x34
#define READ_POSITION         0x34
#define SYNCHRONIZE_CACHE     0x35
#define LOCK_UNLOCK_CACHE     0x36
#define READ_DEFECT_DATA      0x37
#define MEDIUM_SCAN           0x38
#define COMPARE               0x39
#define COPY_VERIFY           0x3a
#define WRITE_BUFFER          0x3b
#define READ_BUFFER           0x3c
#define UPDATE_BLOCK          0x3d
#define READ_LONG             0x3e
#define WRITE_LONG            0x3f
#define CHANGE_DEFINITION     0x40
#define WRITE_SAME            0x41
#define READ_TOC              0x43
#define LOG_SELECT            0x4c
#define LOG_SENSE             0x4d
#define MODE_SELECT_10        0x55
#define RESERVE_10            0x56
#define RELEASE_10            0x57
#define MODE_SENSE_10         0x5a
#define PERSISTENT_RESERVE_IN 0x5e
#define PERSISTENT_RESERVE_OUT 0x5f
#define MOVE_MEDIUM           0xa5
#define READ_12               0xa8
#define WRITE_12              0xaa
#define WRITE_VERIFY_12       0xae
#define SEARCH_HIGH_12        0xb0
#define SEARCH_EQUAL_12       0xb1
#define SEARCH_LOW_12         0xb2
#define READ_ELEMENT_STATUS   0xb8
#define SEND_VOLUME_TAG       0xb6
#define WRITE_LONG_2          0xea


int fd;

int main(void)
{
  Scsi_Ioctl_Command sic = {0};
  char devname[32];
  int loop = 0;
  int nRdevchg = 0;
  int nCount = 0;
  int nSwitchMode = 0;
  
      
 printf("RDEVCHG Linux Version : 1.0\n");
 printf("Please, Wait!\n");
 usleep(2000);
  for(loop = 0; loop < 10 ; loop++ )
  {
          
          sprintf(devname,"/dev/sg%d" , (loop) );
	  fd = open(devname, O_RDWR);
          printf("." );

	  if (fd > 0 ) 
	  {
                  //fprintf(stderr,"/dev/sg%d - IN\n" , (loop) );
		  sic.inlen = 9;
		  sic.outlen = 0;
		  sic.data[0] = 0xFF;
		  memcpy(sic.data + 1, "RDEVCHG1", 8);

		  nRdevchg = ioctl(fd, SCSI_IOCTL_SEND_COMMAND, &sic);
		  close(fd);
                  if( nRdevchg == 0 )
                  { 
                        usleep(2000);
                        nRdevchg = 0;
                        while( nRdevchg < 100)
                        {   
                                nRdevchg++;
                                usleep(1000);
                                if( system("lsusb | grep -i \"16D8:\"") == 0 )
                                {   
                                    printf("\nSuccess SwitchMode.\n");
                                    
                                    return 1;
                                }
                        }
                  }
	  } 
  }
          
  printf("\nFail SwitchMode.\n");

  return 1;
}


